package suncertify.remoting;

import java.rmi.Naming;

import suncertify.application.ApplicationMode;
import suncertify.application.Log;
import suncertify.application.Strings;
import suncertify.application.exceptions.NullEmptyParameterException;
import suncertify.application.exceptions.ServerClientException;

/**
 * Provides remote data access for the client application.
 * 
 */
public class RmiClient {

    /**
     * Provides an implementation for the {@link RemoteContractorsAccess} interface. This interface provides remote
     * access to the applications database. This function is used when the application is running in
     * {@link ApplicationMode#NETWORK_CLIENT} mode.
     * 
     * <p>
     * This function assumes that:
     * <ol>
     * <li>A server application (started with {@link ApplicationMode#SERVER}) is running on the computer defined by
     * <code>hostName</code></li>
     * <li>The server application is started successfully.</li>
     * </ol>
     * 
     * If the two assumptions above are true then this function should return a reference to the interface
     * implementation. If the server is not started, failed to start or a network error occurred then the exception
     * below is thrown.
     * 
     * @param hostName
     *            The name of the remote computer which is running the application in server mode.
     * @param port
     *            The port of the computer which is running the application in server mode.
     * @return Reference to the interface implementation.
     * @throws ServerClientException
     *             If any error occurs in getting the remote reference. This exception is thrown for all
     *             {@link Naming#lookup(String)} declared exceptions. The original exception can be retrieved with
     *             {@link Throwable#getClass()}.
     * @throws NullEmptyParameterException
     *             If the <code>hostName</code> is null or empty.
     * 
     * @see java.rmi.Naming
     * 
     */
    public static RemoteContractorsAccess getContractorsAccess(String hostName, int port) throws ServerClientException {

	if (hostName == null || hostName.trim().isEmpty()) {
	    throw new NullEmptyParameterException("hostName");
	}

	final String RMI_URL_FORMAT = "rmi://%1$s:%2$s/" + RmiServer.REMOTE_CONTRACTORS;
	String url = String.format(RMI_URL_FORMAT, hostName, Integer.toString(port));

	try {
	    RemoteContractorsAccess remoteContractorsAccess = (RemoteContractorsAccess) Naming.lookup(url);
	    Log.logInfo("RmiClient.getContractorsAccess(). Naming.lookup() succeeded on url: " + url);

	    return remoteContractorsAccess;

	} catch (Exception e) {

	    Log.logInfo("RmiClient.getContractorsAccess(). Naming.lookup() failed on url:" + url);
	    throw new ServerClientException(Strings.MSG_SERVER_CLIENT_ERROR, e);
	}
    }
}
